AWS ParallelCluster で Docker コンテナを実行する Docker on ParallelCluster を構築してみた
今やコンテナ技術は Web 界隈だけではなく HPC 界隈でも利用されるほど普及しました。今回は AWS ParallelCluster のコンピュートノード上の計算環境セットアップを省略するべく Docker コンテナを利用した計算処理を実行したいです。
Docker on ParallelCluster を実現する設定ファイルを交え構築方法を紹介します。
Docker on ParallelCluster
項目 | 値 |
---|---|
AWS ParallelCluster | 3.1.3 |
Job Scheduler | Slurm |
OS | Ubuntu 20.04 LTS |
CPU | Intel |
Simultaneous Multi-Threading | Disabled |
コンフィグ
Docker on ParallelCluster 用のサンプルコンフィグを作成しました。Docker に関する部分は postainstall.sh
の処理で行うため、クラスターは自体に特殊な設定は必要ありません。
- ヘッドノードは Docker インストール不要なため、postinsallは未設定
Region: ap-northeast-1 Image: Os: ubuntu2004 Monitoring: Logs: CloudWatch: Enabled: true RetentionInDays: 30 DeletionPolicy: "Delete" Dashboards: CloudWatch: Enabled: false Tags: - Key: Name Value: DockerOnParallelcluster HeadNode: InstanceType: t3.micro Networking: ElasticIp: false SubnetId: subnet-035be95eeaa091603 Ssh: KeyName: sandbox-key LocalStorage: RootVolume: Size: 35 Encrypted: false VolumeType: gp3 Iops: 3000 Throughput: 125 Iam: S3Access: - BucketName: hpc-dev-postinstall-files EnableWriteAccess: False AdditionalIamPolicies: - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore Scheduling: Scheduler: slurm SlurmSettings: ScaledownIdletime: 5 SlurmQueues: # --- Queue 1 --- - Name: cpu-spot ComputeResources: - Name: large InstanceType: c6i.large MinCount: 0 MaxCount: 10 DisableSimultaneousMultithreading: true ComputeSettings: LocalStorage: RootVolume: Size: 35 Encrypted: false VolumeType: gp3 Iops: 3000 Throughput: 125 CapacityType: SPOT Networking: SubnetIds: - subnet-035be95eeaa091603 PlacementGroup: Enabled: true CustomActions: OnNodeConfigured: Script: s3://hpc-dev-postinstall-files/sample-ubuntu-docker/postinstall.sh Iam: S3Access: - BucketName: hpc-dev-postinstall-files EnableWriteAccess: False AdditionalIamPolicies: - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore # --- Queue 2 --- - Name: high-cpu-spot ComputeResources: - Name: large16x InstanceType: c6i.16xlarge MinCount: 0 MaxCount: 10 DisableSimultaneousMultithreading: true ComputeSettings: LocalStorage: RootVolume: Size: 35 Encrypted: false VolumeType: gp3 Iops: 3000 Throughput: 125 CapacityType: SPOT Networking: SubnetIds: - subnet-035be95eeaa091603 PlacementGroup: Enabled: true CustomActions: OnNodeConfigured: Script: s3://hpc-dev-postinstall-files/sample-ubuntu-docker/postinstall.sh Iam: S3Access: - BucketName: hpc-dev-postinstall-files EnableWriteAccess: False AdditionalIamPolicies: - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
postinstall.sh
コンピュートノードの起動時に以下のスクリプトが実行されます。
- Docker のインストール
#! /bin/bash apt-get update apt-get install \ ca-certificates \ curl \ gnupg \ lsb-release -y curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null apt-get update apt-get install docker-ce docker-ce-cli containerd.io -y
コンピュートノードで起動する Ubuntu 20.04 に Docker をインストール手順は公式ドキュメントを参考にしました。
Install Docker Engine on Ubuntu | Docker Documentation
postinstall.sh
はクラスター作成のコンフィグ内で指定した所定のS3バケットに保存します。
ここではhpc-dev-postinstall-files
S3バケットのsample-ubuntu-docker
プレフィックス配下のpostinstall.sh
を指定しています。
コンピュートノードから対象のS3バケットへアクセスできるように読み取り専用の権限を付与しています。
CustomActions: OnNodeConfigured: Script: s3://hpc-dev-postinstall-files/sample-ubuntu-docker/postinstall.sh Iam: S3Access: - BucketName: hpc-dev-postinstall-files EnableWriteAccess: False
クラスター作成
クラスター作成コマンドを実行して10分ほど待ちます。ヘッドノードが起動したらログインします。
> pcluster create-cluster -n DockerOnParallelcluster -c sample-docker-on-parallelcluster.yml { "cluster": { "clusterName": "DockerOnParallelcluster", "cloudformationStackStatus": "CREATE_IN_PROGRESS", "cloudformationStackArn": "arn:aws:cloudformation:ap-northeast-1:12345679012:stack/DockerOnParallelcluster/59b85490-c3a7-11ec-b7c8-0e8a0cc9f27b", "region": "ap-northeast-1", "version": "3.1.3", "clusterStatus": "CREATE_IN_PROGRESS" } }
ヘッドノードからジョブを投げてみる
Docker コンテナを利用するテストジョブを作成しました。今回は BUSCO の動作検証する機会があったため、BUSCO コンテナを起動しています。
- コンテナを起動し、コンテナ内で任意のコマンドを実行
- ジョブを投げたときのカレントディレクトリをコンテナへマウント
- ヘッドノードのホームディレクトリ、EFS、FSx for Lustre などの共有ストレージを想定
- コンテナ内で利用したいファイルを事前に共有ストレージに保存しておくことでコンテナからアクセスできる
- コンテナでの実行結果の出力(保存)先にして永続的なストレージ利用としてもできる
テストジョブ
Slurm で管理されたジョブがコンピュートノードで実行され、コンピュートノード上のコンテナ内で任意コマンド、共有ストレージをマウントできているか確認します。
busco
コマンドが実行可能かテストためバージョン情報表示- コンテナに共有ストレージ(永続的なストレージ)をマウントできているか確認
- 事前に
message.txt
を共有ストレージに作成しcat
コマンドで開けるかテストDocker on ParallelCluster.
と書き込んだテキストファイルです。
ls -l
コマンドで共有ストレージがコンテナ内から見えているかテスト
- 事前に
#! /bin/bash #SBATCH -p cpu-spot #SBATCH -N 1 RUN_CMD="busco -v" RUN_CMD2="cat message.txt" RUN_CMD3="ls -l" CON_WD=/host_mount CON_ID=`sudo docker run -dit --mount type=bind,src=$(pwd),dst=$CON_WD --workdir $CON_WD quay.io/biocontainers/busco:5.3.2--pyhdfd78af_0` sudo docker exec -t ${CON_ID} ${RUN_CMD} sudo docker exec -t ${CON_ID} ${RUN_CMD2} sudo docker exec -t ${CON_ID} ${RUN_CMD3} sudo docker stop ${CON_ID} > /dev/null
ジョブの実行結果
ジョブを投げます。コンピュートノードが起動しpostinstall.sh
が実行され Dockerインストールされた環境が構築されます。その後、run.sh
の内容が実行され、コンテナイメージの取得、任意のコマンド実行されます。
$ sbatch run.sh
実行結果のファイルを確認しました。
sudo doker run ...
コマンドの実行結果が載ってきたため、イメージを pull しているときのメッセージが記録されていました。BUSCO 5.3.2
の表示を確認でき、busco
コマンドを実行できています- すなわちコンテナ内で任意のコマンド実行されたことがわかります。
Docker on ParallelCluster.
の表示を確認できました。- 共有ストレージのファイルをコンテナから開けることを確認
Unable to find image 'quay.io/biocontainers/busco:5.3.2--pyhdfd78af_0' locally 5.3.2--pyhdfd78af_0: Pulling from biocontainers/busco aa44502a478a: Pulling fs layer bef3901422b5: Pulling fs layer b6572cc046f2: Pulling fs layer 6dbbfe98ccd4: Pulling fs layer 4ca545ee6d5d: Pulling fs layer d7cc672bfaf9: Pulling fs layer 6dbbfe98ccd4: Waiting 4ca545ee6d5d: Waiting d7cc672bfaf9: Waiting b6572cc046f2: Verifying Checksum b6572cc046f2: Download complete 6dbbfe98ccd4: Verifying Checksum 6dbbfe98ccd4: Download complete bef3901422b5: Verifying Checksum bef3901422b5: Download complete 4ca545ee6d5d: Verifying Checksum 4ca545ee6d5d: Download complete aa44502a478a: Verifying Checksum aa44502a478a: Download complete aa44502a478a: Pull complete bef3901422b5: Pull complete b6572cc046f2: Pull complete 6dbbfe98ccd4: Pull complete 4ca545ee6d5d: Pull complete d7cc672bfaf9: Verifying Checksum d7cc672bfaf9: Download complete d7cc672bfaf9: Pull complete Digest: sha256:900fc79245c3f6df7b2efe986d030c9a5f6fe21f1f000a4e6f09ff41da7def42 Status: Downloaded newer image for quay.io/biocontainers/busco:5.3.2--pyhdfd78af_0 BUSCO 5.3.2 Docker on ParallelCluster. total 12 -rw-rw-r-- 1 1000 1000 27 Apr 28 11:00 message.txt -rw-rw-r-- 1 1000 1000 434 Apr 28 11:31 run.sh -rw-rw-r-- 1 1000 1000 1147 Apr 28 11:55 slurm-8.out
Docker コンテナを利用した ParallelCluster の実行環境の動作確認が取れました。
まとめ
ParallelCluster で Docker コンテナを利用したい場合は、postinstall.sh
でコンピュートノードに Docker インストールすればコンテナ実行環境が構築できます。
Docker をインストールしても、ジョブを投げてからコンピュートノードが起動しジョブを開始するまで約5分です。Docker をインストール済みのカスタム AMI を作成しなくても実用の範囲内かと思います。
[2022-04-28T11:40:03.797] _slurm_rpc_submit_batch_job: JobId=8 InitPrio=4294901752 usec=347 [2022-04-28T11:40:03.921] sched/backfill: _start_job: Started JobId=8 in cpu-spot on cpu-spot-dy-large-3 [2022-04-28T11:44:15.760] Node cpu-spot-dy-large-3 now responding [2022-04-28T11:44:45.361] job_time_limit: Configuration for JobId=8 complete [2022-04-28T11:44:45.361] Resetting JobId=8 start time for node power up [2022-04-28T11:44:57.639] _job_complete: JobId=8 WEXITSTATUS 0 [2022-04-28T11:44:57.640] _job_complete: requeue JobId=8 per user/system request [2022-04-28T11:44:57.640] _job_complete: JobId=8 done
おわりに
Docker コンテナ使うなら AWS Batch で実現できませんか?という疑問があるかと思います。AWS Batch で利用できるホストの EC2 インスタンスタイプの種類は限定的です。現在 AWS Batch は Hpc6a インスタンスは非対応です。最新のパワフルな計算リソースを使ってみたい方はより自由度の高い ParallelCluster を選択することもあるでしょう。
AWS Batch はフルマネージドでユーザーの運用管理の負担が減るため、自由を得るか、制約のあるなかで楽に利用するかはユースケースに応じて検討してみてください。
Dokcer on ParallelCluster につていは本ブログ内でクラスターコンフィグ、postainstall.sh
の内容を公開しておりますのでお手元で再現できます。ぜひ試して評価してみてください。